home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d909.lha / GoldED2 / Tools / EDSource / main.c next >
C/C++ Source or Header  |  1993-08-28  |  10KB  |  425 lines

  1. /* -----------------------------------------------------------------------------
  2.  
  3.   ED v0.91 - GoldED quick starter, ©1993 Dietmar Eilert. DICE:
  4.  
  5.   dcc main.c -// -proto -mRR -mi -r -2.0 -o ram:ED
  6.  
  7.   ------------------------------------------------------------------------------
  8. */
  9.  
  10. /// "includes"
  11.  
  12. #include <amiga20/exec/exec.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <stdarg.h>
  18. #include <amiga20/intuition/intuition.h>
  19. #include <amiga20/dos/dos.h>
  20. #include <amiga20/dos/dosextens.h>
  21. #include <amiga20/dos/rdargs.h>
  22. #include <amiga20/dos/dostags.h>
  23. #include <amiga20/workbench/startup.h>
  24. #include <amiga20/workbench/workbench.h>
  25. #include <amiga20/rexx/errors.h>
  26. #include <amiga20/rexx/rxslib.h>
  27.  
  28. #include <amiga20/clib/alib_protos.h>
  29. #include <amiga20/clib/dos_protos.h>
  30. #include <amiga20/clib/exec_protos.h>
  31. #include <amiga20/clib/icon_protos.h>
  32. #include <amiga20/clib/intuition_protos.h>
  33. #include <amiga20/clib/utility_protos.h>
  34. #include <amiga20/clib/rexxsyslib_protos.h>
  35. #include <amiga20/clib/wb_protos.h>
  36.  
  37. #ifdef PRAGMAS
  38.  
  39. #include "Pragmas/exec.h"
  40. #include "Pragmas/disk.h"
  41. #include "Pragmas/diskfont.h"
  42. #include "Pragmas/dynamic.h"
  43. #include "Pragmas/gadtools.h"
  44. #include "Pragmas/keymap.h"
  45. #include "Pragmas/graphics.h"
  46. #include "Pragmas/icon.h"
  47. #include "Pragmas/input.h"
  48. #include "Pragmas/intuition.h"
  49. #include "Pragmas/layers.h"
  50. #include "Pragmas/locale.h"
  51. #include "Pragmas/misc.h"
  52. #include "Pragmas/timer.h"
  53. #include "Pragmas/wb.h"
  54. #include "Pragmas/xpkmaster.h"
  55. #include "Pragmas/amigaguide.h"
  56. #include "Pragmas/reqtools.h"
  57.  
  58. #endif
  59.  
  60. #define Prototype        extern
  61. #define MAX_LEN          120
  62. #define ARGBUFFER_SIZE   10500
  63. #define ARGBUFFER_LIMIT  10000
  64.  
  65. ///
  66. /// "prototypes"
  67.  
  68. Prototype void   main(ULONG, char **);
  69. Prototype int    wbmain(struct WBStartup *);
  70. Prototype void   Action(char *, char *, char *, BOOL, BOOL);
  71. Prototype char  *StartGED(char *, char *, BOOL);
  72. Prototype struct RexxMsg *SendRexxCommand(char *, char *, struct MsgPort *);
  73. Prototype void   FreeRexxCommand (struct RexxMsg *);
  74. Prototype ULONG  WaitForAnswer(struct MsgPort *);
  75. Prototype char  *QuotedString(char *);
  76.  
  77. extern struct Library *IconBase;
  78. extern struct Library *DOSBase;
  79. extern struct Library *SysBase;
  80. extern struct Library *IntuitionBase;
  81.  
  82. ///
  83. /// "entry points"
  84.  
  85. /* --------------------------------------- main --------------------------------
  86.  
  87.  CLI entry point. Parse command line - create a string <argBuffer> containing
  88.  provided file names (file names are made absolute). This string has to be
  89.  FreeVec()'ed later on. Additionally, command line options are checked. They
  90.  won't have any effect if we manage to pass our list of files to a GoldED
  91.  process since we than have to accept that editor's configuration. However,
  92.  these options will be considered if we launch a new GoldED process.
  93.  
  94. */
  95.  
  96. void
  97. main(argc, argv)
  98.  
  99. ULONG argc;
  100. char *argv[];
  101. {
  102.     char *argBuffer;
  103.  
  104.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  105.  
  106.         struct RDArgs *rdArgs;
  107.         ULONG  args[] = { 0, 0, 0, 0, 0 };
  108.  
  109.         if (rdArgs = ReadArgs("C=CONFIG/K,S=SCREEN/K,Y=STICKY/S,F=FILE/M,HIDE/S", args, NULL)) {
  110.  
  111.             if (args[3]) {
  112.  
  113.                 char **nextFile, path[MAX_LEN + 1];
  114.  
  115.                 for (nextFile = (char **)args[3]; *nextFile; ++nextFile) {
  116.  
  117.                     BPTR lock;
  118.  
  119.                     strcpy(path, *nextFile);
  120.  
  121.                     if (lock = Lock(path, ACCESS_READ)) {
  122.  
  123.                         NameFromLock(lock, path, MAX_LEN);
  124.                         UnLock(lock);
  125.  
  126.                     }
  127.                     strcat(argBuffer, QuotedString(path));
  128.  
  129.                     if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  130.                         break;
  131.                 }
  132.             }
  133.  
  134.             Action(argBuffer, (char *)args[0], (char *)args[1], (BOOL)args[2], (BOOL)args[4]);
  135.             FreeArgs(rdArgs);
  136.         }
  137.         else
  138.             exit(20);
  139.     }
  140.     exit(0);
  141. }
  142.  
  143. /* ------------------------------------ wbmain ---------------------------------
  144.  
  145.   Workbench  entry  point.  Read  tooltypes  of ED icon to decide wether user
  146.   prefers   a   special   configuration/public  screen.  Tooltypes  are  only
  147.   considered if we don't find a running GoldED task, i.e. if we don't have to
  148.   acccept a running environment.
  149.  
  150. */
  151.  
  152. int
  153. wbmain(struct WBStartup *wbs)
  154. {
  155.     char *argBuffer;
  156.  
  157.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  158.  
  159.         struct DiskObject *diskObject;
  160.         char   *config, *screen, progName[MAX_LEN + 1];
  161.         BOOL   hide;
  162.  
  163.         screen = NULL;
  164.         config = NULL;
  165.         hide   = FALSE;
  166.  
  167.         NameFromLock(GetProgramDir(), progName, MAX_LEN);
  168.  
  169.         AddPart(progName, wbs->sm_ArgList[0].wa_Name, MAX_LEN);
  170.  
  171.         if (diskObject = GetDiskObject(progName)) {
  172.  
  173.             config   = FindToolType(diskObject->do_ToolTypes, "CONFIG");
  174.             screen   = FindToolType(diskObject->do_ToolTypes, "SCREEN");
  175.  
  176.             if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
  177.                 hide = TRUE;
  178.         }
  179.  
  180.         if (--wbs->sm_NumArgs) {
  181.  
  182.             char   file[MAX_LEN + 1];
  183.             struct WBArg *wbArg = wbs->sm_ArgList;
  184.  
  185.             while ((wbs->sm_NumArgs)--) {
  186.  
  187.                 ++wbArg;
  188.  
  189.                 NameFromLock( wbArg->wa_Lock, file, MAX_LEN);
  190.                 AddPart(file, wbArg->wa_Name, MAX_LEN);
  191.  
  192.                 strcat(argBuffer, QuotedString(file));
  193.  
  194.                 if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  195.                     break;
  196.             }
  197.         }
  198.  
  199.         Action(argBuffer, config, screen, FALSE, hide);
  200.  
  201.         if (diskObject)
  202.             FreeDiskObject(diskObject);
  203.     }
  204.     exit(0);
  205. }
  206.  
  207. ///
  208. /// "main routine"
  209.  
  210. /* ------------------------------------ Action ---------------------------------
  211.  
  212.   Send  LOCK  ARexx messages to running GoldED. Wait for positive reply, pass
  213.   our  list  of  <files>  to  that  editor, unlock editor (use delayed unlock
  214.   unless <sticky> is specified). Suggestions for improvements: Make the whole
  215.   thing  aynchrounous. Send LOCK messages to all running instances of GoldED,
  216.   then wait for first reply (or timeout).
  217.  
  218. */
  219.  
  220. void
  221. Action(files, config, screen, sticky, hide)
  222.  
  223. char *files, *config, *screen;
  224. BOOL sticky, hide;
  225. {
  226.     BOOL success = FALSE;
  227.     char *host;
  228.  
  229.     if (host = StartGED(config, screen, hide)) {
  230.  
  231.         if (*files || !hide) {
  232.  
  233.             struct MsgPort *replyPort;
  234.  
  235.             if (replyPort = CreateMsgPort()) {
  236.  
  237.                 if (SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
  238.  
  239.                     if (success = (WaitForAnswer(replyPort) == RC_OK)) {
  240.  
  241.                         if (*files)
  242.                             strins(files, "OPEN SMART QUIET ");
  243.                         else
  244.                             strcpy(files, "MORE SMART");
  245.  
  246.                         if (SendRexxCommand(host, files, replyPort))
  247.                             WaitForAnswer(replyPort);
  248.  
  249.                         if (SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK DELAY", replyPort))
  250.                             WaitForAnswer(replyPort);
  251.                     }
  252.                 }
  253.                 DeleteMsgPort(replyPort);
  254.             }
  255.         }
  256.     }
  257.     FreeVec(files);
  258. }
  259.  
  260. ///
  261. /// "misc"
  262.  
  263.  
  264. /* ------------------------------------- StartGED -----------------------------
  265.  
  266.   Look  for  running  instance of GoldED. Launch a new task if none is found.
  267.   Return  pointer  to  host  name  (or NULL). Screen/config keywords are only
  268.   considered  if  a  new GoldED process has to be launched, i.e. if we aren't
  269.   bound to an existing environment.
  270.  
  271. */
  272.  
  273. char *
  274. StartGED(config, screen, hide)
  275.  
  276. char *config, *screen;
  277. BOOL hide;
  278. {
  279.     static char host[] = "GOLDED.1";
  280.     char   command[MAX_LEN + 1];
  281.     UWORD  try;
  282.  
  283.     for (try = '9'; try >= '1'; try--) {
  284.  
  285.         host[7] = try;
  286.  
  287.         if (FindPort(host))
  288.             return(host);
  289.     } 
  290.  
  291.     strcpy(command, "GoldED:GoldED ");
  292.  
  293.     if (hide)
  294.         strcat(command, "HIDE ");
  295.  
  296.     if (config) {
  297.  
  298.         strcat(command, "CONFIG ");
  299.         strcat(command, QuotedString(config));
  300.     }
  301.     if (screen) {
  302.  
  303.         strcat(command, "SCREEN ");
  304.         strcat(command, QuotedString(screen));
  305.     }
  306.  
  307.     if (!SystemTags(command, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, TAG_DONE))
  308.  
  309.         for (try = 50; try; try--, Delay(10))
  310.             if (FindPort(host))
  311.                 return(host);
  312.  
  313.     return(FALSE);
  314. }
  315.  
  316.  
  317. /* ------------------------------------ QuotedString --------------------------
  318.  
  319.  Add quotation marks to string (to avoid import of sprintf)
  320.  
  321. */
  322.  
  323. char *
  324. QuotedString(char *text)
  325. {
  326.     static char buffer[MAX_LEN + 1];
  327.  
  328.     strcpy(buffer, "\42");
  329.     strcat(buffer, text );
  330.     strcat(buffer, "\42");
  331.  
  332.     return(buffer);
  333. }
  334.  
  335. ///
  336. /// "ARexx"
  337.  
  338. /* -------------------------------------- WaitForAnswer -----------------------
  339.  
  340.   Wait  for  answer  on  previously  sent  message.  Free message afterwards.
  341.   Primary return code is returned.
  342.  
  343. */
  344.  
  345. ULONG
  346. WaitForAnswer(port)
  347.  
  348. struct MsgPort *port;
  349. {
  350.     struct RexxMsg *rexxMsg;
  351.     ULONG  result;
  352.  
  353.     do {
  354.         
  355.         WaitPort(port);
  356.  
  357.         if (rexxMsg = (struct RexxMsg *)GetMsg(port))
  358.             result = rexxMsg->rm_Result1;
  359.  
  360.     } while (!rexxMsg);
  361.  
  362.     FreeRexxCommand(rexxMsg);
  363.  
  364.     return(result);
  365. }
  366.  
  367. /* ------------------------------------- FreeRexxCommand ----------------------
  368.  
  369.  Free ARexx message
  370.  
  371. */
  372.  
  373. void
  374. FreeRexxCommand(rexxmessage)
  375.  
  376. struct RexxMsg *rexxmessage;
  377. {
  378.     if (rexxmessage->rm_Result1 == RC_OK) 
  379.         if (rexxmessage->rm_Result2)
  380.             DeleteArgstring((char *)rexxmessage->rm_Result2);
  381.  
  382.     DeleteArgstring((char *)ARG0(rexxmessage));
  383.  
  384.     DeleteRexxMsg(rexxmessage);
  385. }
  386.  
  387. /* ---------------------------------- SendRexxCommand -------------------------
  388.  
  389.  Send ARexx message
  390.  
  391. */
  392.  
  393. struct RexxMsg *
  394. SendRexxCommand(port, cmd, replyPort)
  395.  
  396. char   *cmd,   *port;
  397. struct MsgPort *replyPort;
  398. {
  399.     struct MsgPort *rexxport;
  400.     struct RexxMsg *rexx_command_message = NULL;
  401.  
  402.     Forbid();
  403.  
  404.     if (rexxport = FindPort(port)) {
  405.  
  406.         if (rexx_command_message = CreateRexxMsg(replyPort, NULL, NULL)) {
  407.  
  408.             if (rexx_command_message->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
  409.  
  410.                 rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
  411.  
  412.                 PutMsg(rexxport, &rexx_command_message->rm_Node);
  413.             }
  414.         }
  415.     }
  416.  
  417.     Permit();
  418.  
  419.     return(rexx_command_message);
  420. }
  421.  
  422.  
  423.  
  424. ///
  425.